
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>原型链</title>
</head>
<body>
    
    <script>
        /*
        1.概念：
            当我们去访问对象的一个属性或调用对象的一个方法时，它会先自身中寻找，如果在自身中找到了，则直接使用。
            如果没有找到，则去原型对象中寻找，如果找到了则使用，
            如果没有找到，则去原型的原型中寻找，依此类推。直到找到Object的原型为止，Object的原型的原型为null，
            如果依然没有找到则返回undefined
         
        2.检测是否存在属性： 
            in:首先在自己身上查找，找不到去原型链上查找
            hasOwnProperty：只是检测自己的属性(构造函数实例中)，不检查原型链，不会向上查找
          
        3.原型链作用：
            数据的继承
        4.应用场景（了解即可暂时）：
            封装api请求层 Vue.prototype.$api = api
            第三方库的使用(router vuex element-ui)
        */

        function Person() {
            this.name = "mary"

        }

        Person.prototype.$age = 18;
        Person.prototype.$userName = "king";

        let obj = new Person()
        console.log(obj.name);
        console.log(obj.$age);
        console.log(obj.$userName);
        // hasOwnProperty:如何判断属性是在构造函数实例里  不在原型当中
        console.log(Person.hasOwnProperty("name"));
        console.log(Person.hasOwnProperty("$age"));
        console.log(Person.hasOwnProperty("$userName"));
        
        //  “in” 操作符会在通过对象能够访问给定属性时返回true,无论该属性存在于实例中还是原型中
        console.log("name" in Person);
        console.log("$age" in obj);
        console.log("$userName" in obj);


        console.log(obj.__proto__.hasOwnProperty("$age"));  //true
        console.log(obj.__proto__.__proto__.hasOwnProperty("hasOwnProperty"));  //true


        
        


    </script>

</body>
</html>